package com.lu.component.http.proxy;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.*;
import com.lu.component.http.proxy.clients.RpcInvocationHandler;
import com.lu.component.http.proxy.config.RpcApplicationContext;
import com.lu.component.rpc.utils.ClassLoaderFindUtil;
import com.lu.component.rpc.Driver;
import com.lu.component.rpc.annotations.EnableRpcClients;
import com.lu.component.rpc.annotations.RpcClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Proxy;
import java.util.*;
import java.util.stream.Collectors;

/**
 * http请求代理配置
 *
 * @author: zhanglu
 * @date: 2023/7/6 17:53
 * @modify: 修改人信息, 修改内容 2023/7/6 17:53
 */
public class HttpProxyConfiguration implements Driver {

    private static final Logger log = LoggerFactory.getLogger(HttpProxyConfiguration.class);

    @Override
    public void init() {
        //查找EnableRpcClients#basePackages和clients
        Set<Class<?>> classes = ClassLoaderFindUtil.getClassSet();
        //找到配置该注解的类
        List<Class<?>> enableRpcClients = classes.stream().filter(o -> o.getAnnotation(EnableRpcClients.class) != null).collect(Collectors.toList());
        if(ObjectUtil.isEmpty(enableRpcClients)){
            return;
        }
        //根据搜索条件搜索rpc配置的接口类
        List<Class<?>> rpcClients = classes.stream().filter(o -> {
            boolean exist = false;
            String name = o.getName();
            endLoop:
            for (Class<?> enableRpcClientClass : enableRpcClients) {
                EnableRpcClients enableRpcClient = enableRpcClientClass.getAnnotation(EnableRpcClients.class);
                for (String basePackage : enableRpcClient.basePackages()) {
                    if (StrUtil.startWith(name, basePackage)) {
                        exist = true;
                        break endLoop;
                    }
                }
                for (Class<?> client : enableRpcClient.clients()) {
                    if (Objects.equals(name, client.getName())) {
                        exist = true;
                        break endLoop;
                    }
                }
            }
            if(!exist){
                return false;
            }
            //检查当前rpc配置类，是否是接口类
            if(!o.isInterface()){
                if(Arrays.stream(o.getInterfaces()).anyMatch(c -> c.getAnnotation(RpcClient.class) != null
                        && Objects.equals(c.getAnnotation(RpcClient.class).fallback(), o))){
                    return false;
                }
                log.warn(CharSequenceUtil.format("{} [rpc-http proxy ignore] is not interface class", name));
                return false;
            }
            //检查当前rpc配置类是否，配置了RpcClient注解
            if(o.getAnnotation(RpcClient.class) == null){
                log.warn(CharSequenceUtil.format("{} [rpc-http proxy ignore] is not modified RpcClient annotation", name));
                return false;
            }
            return true;
        }).collect(Collectors.toList());
        for (Class<?> rpcClient : rpcClients) {
            //设置代理
            Object obj = Proxy.newProxyInstance(rpcClient.getClassLoader(), new Class[]{rpcClient}, new RpcInvocationHandler(rpcClient));
            //代理加入Map(单例)
            RpcApplicationContext.RPC_CLIENT_PROXY_CLASS_BEAN_MAP.put(rpcClient, obj);
        }
    }

}
